home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / Emulation_Include_Files / kxppc.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  30.1 KB  |  927 lines

  1. //*++
  2. //
  3. // Copyright (c) 1997-1998 Microsoft Corporation
  4. //
  5. // Module Name:
  6. //
  7. //  kxppc.h
  8. //
  9. // Abstract:
  10. //
  11. //  This module contains the nongenerated part of the PPC assembler
  12. //  header file. In general, it contains processor architecture constant
  13. //  information, however some assembler macros are also included.
  14. //
  15. //--*/
  16.  
  17. #ifndef _KXPPC_
  18. #define _KXPPC_
  19.  
  20. #define ASM_ONLY
  21.  
  22.  
  23.  
  24.  
  25. //
  26. // Macro to generate a mask using the SPR bit definitions below
  27. //
  28. #define BITMASK(shift,mask)  ((mask) << (31-(shift)))
  29.  
  30.  
  31. //
  32. // Register #'s for special purpose registers
  33. //
  34. #define XER     1
  35. #define DECRMEMENTER     22
  36. #define SRR0    26
  37. #define SRR1    27
  38. #define SPRG0   272
  39. #define SPRG1   273
  40. #define SPRG2   274
  41. #define SPRG3   275
  42. #define TBL     284
  43. #define TBH     285
  44. #define PVR     287
  45.  
  46.  
  47.  
  48. //
  49. // Define Machine State Register bit field offsets.
  50. //
  51. // MSR_BIT_POW   0x0d Power management enable         <13>
  52. // MSR_BIT_IMPL  0x0e Implementation dependent        <14>
  53. // MSR_BIT_ILE   0x0f Interrupt Little-Endian mode    <15>
  54. // MSR_BIT_EE    0x10 External interrupt Enable       <16>
  55. // MSR_BIT_PR    0x11 Problem state                   <17>
  56. // MSR_BIT_FP    0x12 Floating Point available        <18>
  57. // MSR_BIT_ME    0x13 Machine check Enable            <19>
  58. // MSR_BIT_FE0   0x14 Floating point Exception mode 0 <20>
  59. // MSR_BIT_SE    0x15 Single-step trace Enable        <21>
  60. // MSR_BIT_BE    0x16 Branch trace Enable             <22>
  61. // MSR_BIT_FE1   0x17 Floating point Exception mode 1 <23>
  62. // MSR_BIT_IP    0x19 Interrupt Prefix                <25>
  63. // MSR_BIT_IR    0x1a Instruction Relocate            <26>
  64. // MSR_BIT_DR    0x1b Data Relocate                   <27>
  65. // MSR_BIT_RI    0x1e Recoverable Interrupt           <30>
  66. // MSR_BIT_LE    0x1f Little-Endian execution mode    <31>
  67. //
  68. #define MSR_BIT_POW   0x0d
  69. #define MSR_BIT_IMPL  0x0e
  70. #define MSR_BIT_ILE   0x0f
  71. #define MSR_BIT_EE    0x10
  72. #define MSR_BIT_PR    0x11
  73. #define MSR_BIT_FP    0x12
  74. #define MSR_BIT_ME    0x13
  75. #define MSR_BIT_FE0   0x14
  76. #define MSR_BIT_SE    0x15
  77. #define MSR_BIT_BE    0x16
  78. #define MSR_BIT_FE1   0x17
  79. #define MSR_BIT_IP    0x19
  80. #define MSR_BIT_IR    0x1a
  81. #define MSR_BIT_DR    0x1b
  82. #define MSR_BIT_RI    0x1e
  83. #define MSR_BIT_LE    0x1f
  84.  
  85. #define MSR_POW   (BITMASK(MSR_BIT_POW,1))
  86. #define MSR_IMPL  (BITMASK(MSR_BIT_IMPL,1))
  87. #define MSR_ILE   (BITMASK(MSR_BIT_ILE,1))
  88. #define MSR_EE    (BITMASK(MSR_BIT_EE,1))
  89. #define MSR_PR    (BITMASK(MSR_BIT_PR,1))
  90. #define MSR_FP    (BITMASK(MSR_BIT_FP,1))
  91. #define MSR_ME    (BITMASK(MSR_BIT_ME,1))
  92. #define MSR_FE0   (BITMASK(MSR_BIT_FE0,1))
  93. #define MSR_SE    (BITMASK(MSR_BIT_SE,1))
  94. #define MSR_BE    (BITMASK(MSR_BIT_BE,1))
  95. #define MSR_FE1   (BITMASK(MSR_BIT_FE1,1))
  96. #define MSR_IP    (BITMASK(MSR_BIT_IP,1))
  97. #define MSR_IR    (BITMASK(MSR_BIT_IR,1))
  98. #define MSR_DR    (BITMASK(MSR_BIT_DR,1))
  99. #define MSR_RI    (BITMASK(MSR_BIT_RI,1))
  100. #define MSR_LE    (BITMASK(MSR_BIT_LE,1))
  101.  
  102.  
  103. //
  104. // Define Processor Version Register (PVR) bit fields
  105. //
  106. //  PVR_BIT_Version  0x0  Processor Version  <0:15>
  107. //  PVR_BIT_Revision 0x10 Processor Revision <16:31>
  108. //
  109. #define PVR_BIT_Version  0x0
  110. #define PVR_BIT_Revision 0x10
  111.  
  112. #define PVR_Version  (BITMASK(PVR_BIT_Version, 0xFFFF))
  113. #define PVR_Revision (BITMASK(PVR_BIT_Revision, 0xFFFF))
  114.  
  115.  
  116. //
  117. // Define Fixed Point Exception Register (XER) bit fields
  118. //
  119.  
  120. // XER_BIT_SO    0x0  Summary Overflow <0>
  121. // XER_BIT_OV    0x1  Overflow         <1>
  122. // XER_BIT_CA    0x2  Carry            <2>
  123. // XER_BIT_COMP  0x10 > Carry          <16:23>
  124. // XER_BIT_COUNT 0x19 Carry            <25:31>
  125.  
  126. #define XER_BIT_SO    0x0
  127. #define XER_BIT_OV    0x1
  128. #define XER_BIT_CA    0x2
  129. #define XER_BIT_COMP  0x10
  130. #define XER_BIT_COUNT 0x19
  131.  
  132. #define XER_SO    (BITMASK(XER_BIT_SO, 1))
  133. #define XER_OV    (BITMASK(XER_BIT_OV, 1))
  134. #define XER_CA    (BITMASK(XER_BIT_CA, 1))
  135. #define XER_COMP  (BITMASK(XER_BIT_COMP, 0xFF))
  136. #define XER_COUNT (BITMASK(XER_BIT_COUNT, 0x7F))
  137.  
  138.  
  139.  
  140. //
  141. // Define Floating Point Status/Control Register (FPSCR) bit fields
  142. //
  143. // FPSCR_BIT_FX        0x0  Exception summary                          <0>
  144. // FPSCR_BIT_FEX       0x1  Enabled Exception summary                  <1>
  145. // FPSCR_BIT_VX        0x2  Invalid operation exception summary        <2>
  146. // FPSCR_BIT_OX        0x3  Overflow exception                         <3>
  147. // FPSCR_BIT_UX        0x4  Underflow exception                        <4>
  148. // FPSCR_BIT_ZX        0x5  Zero divide exception                      <5>
  149. // FPSCR_BIT_XX        0x6  Inexact exception                          <6>
  150. // FPSCR_BIT_VXSNAN    0x7  Invalid op exception (signalling NaN)      <7>
  151. // FPSCR_BIT_VXISI     0x8  Invalid op exception (infinity - infinity) <8>
  152. // FPSCR_BIT_VXIDI     0x9  Invalid op exception (infinity / infinity) <9>
  153. // FPSCR_BIT_VXZDZ     0x0a Invalid op exception (0 / 0)               <10>
  154. // FPSCR_BIT_VXIMZ     0x0b Invalid op exception (infinity * 0)        <11>
  155. // FPSCR_BIT_VXVC      0x0c Invalid op exception (compare)             <12>
  156. // FPSCR_BIT_FR        0x0d Fraction Rounded                           <13>
  157. // FPSCR_BIT_FI        0x0e Fraction Inexact                           <14>
  158. // FPSCR_BIT_C         0x0f Result Class descriptor                    <15>
  159. // FPSCR_BIT_FL        0x10 Result Less than or negative               <16>
  160. // FPSCR_BIT_FG        0x11 Result Greater than or positive            <17>
  161. // FPSCR_BIT_FE        0x12 Result Equal or zero                       <18>
  162. // FPSCR_BIT_FU        0x13 Result Unordered or NaN                    <19>
  163. // FPSCR_BIT_Res1      0x14 reserved                                   <20>
  164. // FPSCR_BIT_VXSOFT    0x15 Invalid op exception (software request)    <21>
  165. // FPSCR_BIT_VXSQRT    0x16 Invalid op exception (square root)         <22>
  166. // FPSCR_BIT_VXCVI     0x17 Invalid op exception (integer convert)     <23>
  167. // FPSCR_BIT_VE        0x18 Invalid operation exception Enable         <24>
  168. // FPSCR_BIT_OE        0x19 Overflow exception Enable                  <25>
  169. // FPSCR_BIT_UE        0x1a Underflow exception Enable                 <26>
  170. // FPSCR_BIT_ZE        0x1b Zero divide exception Enable               <27>
  171. // FPSCR_BIT_XE        0x1c Inexact exception Enable                   <28>
  172. // FPSCR_BIT_NI        0x1d Non-IEEE mode                              <29>
  173. // FPSCR_BIT_RN        0x1e Rounding control                        <30:31>
  174.  
  175. #define FPSCR_BIT_FX        0x0
  176. #define FPSCR_BIT_FEX       0x1
  177. #define FPSCR_BIT_VX        0x2
  178. #define FPSCR_BIT_OX        0x3
  179. #define FPSCR_BIT_UX        0x4
  180. #define FPSCR_BIT_ZX        0x5
  181. #define FPSCR_BIT_XX        0x6
  182. #define FPSCR_BIT_VXSNAN    0x7
  183. #define FPSCR_BIT_VXISI     0x8
  184. #define FPSCR_BIT_VXIDI     0x9
  185. #define FPSCR_BIT_VXZDZ     0x0a
  186. #define FPSCR_BIT_VXIMZ     0x0b
  187. #define FPSCR_BIT_VXVC      0x0c
  188. #define FPSCR_BIT_FR        0x0d
  189. #define FPSCR_BIT_FI        0x0e
  190. #define FPSCR_BIT_C         0x0f
  191. #define FPSCR_BIT_FL        0x10
  192. #define FPSCR_BIT_FG        0x11
  193. #define FPSCR_BIT_FE        0x12
  194. #define FPSCR_BIT_FU        0x13
  195. #define FPSCR_BIT_Res1      0x14
  196. #define FPSCR_BIT_VXSOFT    0x15
  197. #define FPSCR_BIT_VXSQRT    0x16
  198. #define FPSCR_BIT_VXCVI     0x17
  199. #define FPSCR_BIT_VE        0x18
  200. #define FPSCR_BIT_OE        0x19
  201. #define FPSCR_BIT_UE        0x1a
  202. #define FPSCR_BIT_ZE        0x1b
  203. #define FPSCR_BIT_XE        0x1c
  204. #define FPSCR_BIT_NI        0x1d
  205. #define FPSCR_BIT_RN        0x1e
  206.  
  207. #define FPSCR_FX        (BITMASK(FPSCR_FX, 1))
  208. #define FPSCR_FEX       (BITMASK(FPSCR_FEX, 1))
  209. #define FPSCR_VX        (BITMASK(FPSCR_VX, 1))
  210. #define FPSCR_OX        (BITMASK(FPSCR_OX, 1))
  211. #define FPSCR_UX        (BITMASK(FPSCR_UX, 1))
  212. #define FPSCR_ZX        (BITMASK(FPSCR_ZX, 1))
  213. #define FPSCR_XX        (BITMASK(FPSCR_XX, 1))
  214. #define FPSCR_VXSNAN    (BITMASK(FPSCR_VXSNAN, 1))
  215. #define FPSCR_VXISI     (BITMASK(FPSCR_VXISI, 1))
  216. #define FPSCR_VXIDI     (BITMASK(FPSCR_VXIDI, 1))
  217. #define FPSCR_VXZDZ     (BITMASK(FPSCR_VXZDZ, 1))
  218. #define FPSCR_VXIMZ     (BITMASK(FPSCR_VXIMZ, 1))
  219. #define FPSCR_VXVC      (BITMASK(FPSCR_VXVC, 1))
  220. #define FPSCR_FR        (BITMASK(FPSCR_FR, 1))
  221. #define FPSCR_FI        (BITMASK(FPSCR_FI, 1))
  222. #define FPSCR_C         (BITMASK(FPSCR_C, 1))
  223. #define FPSCR_FL        (BITMASK(FPSCR_FL, 1))
  224. #define FPSCR_FG        (BITMASK(FPSCR_FG, 1))
  225. #define FPSCR_FE        (BITMASK(FPSCR_FE, 1))
  226. #define FPSCR_FU        (BITMASK(FPSCR_FU, 1))
  227. #define FPSCR_Res1      (BITMASK(FPSCR_Res1, 1))
  228. #define FPSCR_VXSOFT    (BITMASK(FPSCR_VXSOFT, 1))
  229. #define FPSCR_VXSQRT    (BITMASK(FPSCR_VXSQRT, 1))
  230. #define FPSCR_VXCVI     (BITMASK(FPSCR_VXCVI, 1))
  231. #define FPSCR_VE        (BITMASK(FPSCR_VE, 1))
  232. #define FPSCR_OE        (BITMASK(FPSCR_OE, 1))
  233. #define FPSCR_UE        (BITMASK(FPSCR_UE, 1))
  234. #define FPSCR_ZE        (BITMASK(FPSCR_ZE, 1))
  235. #define FPSCR_XE        (BITMASK(FPSCR_XE, 1))
  236. #define FPSCR_NI        (BITMASK(FPSCR_NI, 1))
  237. #define FPSCR_RN        (BITMASK(FPSCR_RN, 3))
  238.  
  239.  
  240.  
  241. #ifndef _KXPPC_C_HEADER_
  242.  
  243. //
  244. // Define global definition macros.
  245. //
  246.  
  247. //
  248. // Define load immediate macro for 32-bit values.
  249. //
  250. //      reg       - Register to load with the 32-bit immediate
  251. //      immediate - 32-bit immediate value
  252. //
  253. #define LWI(reg,immediate)   \
  254.        .lwi reg, (immediate)
  255.  
  256.  
  257.  
  258. //
  259. // Define macros used by procedure entry/exit macros
  260. //
  261. // Note that these macros are not intended to be used except in this file.
  262. //
  263.  
  264.  
  265. //
  266. //  Alignment macro to align a constant address to the next 8 byte boundary
  267. //   (a double word boundary)
  268. //
  269. #define ALIGN8(addr)  (  ((addr)+7) & ~0x7  )
  270.  
  271.  
  272.  
  273. //
  274. //  __savegpr0  Used for storing no non-volatile GPRs.  Saves only the LR.
  275. //   ...
  276. //  __savegpr17 Used for storing 17 non-volatile GPRs.  Also saves the LR.
  277. //
  278. // Stores a non-volatile GPR and moves the link register into it.  Next, the
  279. // requested number of GPRs to be saved are saved either inline or by branching
  280. // to millicode routines.
  281. //
  282. // GPRs are stored relative to the caller's stack pointer when the prologue is
  283. // entered.  Note that r1 is always aligned on an 8 byte boundary.
  284. //
  285.  
  286. #define __savegpr0        \
  287.     stw     r31, -4(r1)   ;\
  288.     mflr    r31
  289.  
  290. #define __savegpr1        \
  291.     stw     r30, -8(r1)   ;\
  292.     mflr    r30           ;\
  293.     stw     r31, -4(r1)
  294.  
  295. #define __savegpr2        \
  296.     stw     r29, -12(r1)  ;\
  297.     mflr    r29           ;\
  298.     stw     r31,  -4(r1)  ;\
  299.     stw     r30,  -8(r1)
  300.  
  301. #define __savegpr3        \
  302.     stw     r28, -16(r1)  ;\
  303.     mflr    r28           ;\
  304.     stw     r31,  -4(r1)  ;\
  305.     stw     r30,  -8(r1)  ;\
  306.     stw     r29, -12(r1)
  307.  
  308. #define __savegpr4        \
  309.     stw     r27, -20(r1)  ;\
  310.     mflr    r27           ;\
  311.     bl      __savegpr_28
  312.  
  313. #define __savegpr5        \
  314.     stw     r26, -24(r1)  ;\
  315.     mflr    r26           ;\
  316.     bl      __savegpr_27
  317.  
  318. #define __savegpr6        \
  319.     stw     r25, -28(r1)  ;\
  320.     mflr    r25           ;\
  321.     bl      __savegpr_26
  322.  
  323. #define __savegpr7        \
  324.     stw     r24, -32(r1)  ;\
  325.     mflr    r24           ;\
  326.     bl      __savegpr_25
  327.  
  328. #define __savegpr8        \
  329.     stw     r23, -36(r1)  ;\
  330.     mflr    r23           ;\
  331.     bl      __savegpr_24
  332.  
  333. #define __savegpr9        \
  334.     stw     r22, -40(r1)  ;\
  335.     mflr    r22           ;\
  336.     bl      __savegpr_23
  337.  
  338. #define __savegpr10       \
  339.     stw     r21, -44(r1)  ;\
  340.     mflr    r21           ;\
  341.     bl      __savegpr_22
  342.  
  343. #define __savegpr11       \
  344.     stw     r20, -48(r1)  ;\
  345.     mflr    r20           ;\
  346.     bl      __savegpr_21
  347.  
  348. #define __savegpr12       \
  349.     stw     r19, -52(r1)  ;\
  350.     mflr    r19           ;\
  351.     bl      __savegpr_20
  352.  
  353. #define __savegpr13       \
  354.     stw     r18, -56(r1)  ;\
  355.     mflr    r18           ;\
  356.     bl      __savegpr_19
  357.  
  358. #define __savegpr14       \
  359.     stw     r17, -60(r1)  ;\
  360.     mflr    r17           ;\
  361.     bl      __savegpr_18
  362.  
  363. #define __savegpr15       \
  364.     stw     r16, -64(r1)  ;\
  365.     mflr    r16           ;\
  366.     bl      __savegpr_17
  367.  
  368. #define __savegpr16       \
  369.     stw     r15, -68(r1)  ;\
  370.     mflr    r15           ;\
  371.     bl      __savegpr_16
  372.  
  373. #define __savegpr17       \
  374.     stw     r14, -72(r1)  ;\
  375.     mflr    r14           ;\
  376.     bl      __savegpr_15
  377.  
  378.  
  379.  
  380. //
  381. // __savefpr0  Used to save no FPRs.
  382. //  ...
  383. // __savefpr19 Used to save 19 FPRs.
  384. //
  385. //  Gprs - Number of GPRs to be saved
  386. //
  387. // Saves the number of FPRs specified inline or by branching to the appropriate
  388. // millicode procedure.  The routine sets up r12 to be the base of the FPR
  389. // save area.  FPRs must be double word aligned (on 8 byte boundaries) so
  390. // r12 is adjusted according to the number of GPRs saved.  One word of pad may
  391. // be inserted if an odd number of GPRs was saved.
  392. //
  393.  
  394. #define __savefpr0(Gprs)          
  395.  
  396. #define __savefpr1(Gprs)                     \
  397.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  398.     stfd    f31,  -8(r12)
  399.  
  400. #define __savefpr2(Gprs)                     \
  401.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  402.     stfd    f31,  -8(r12)                    ;\
  403.     stfd    f30, -16(r12)
  404.  
  405. #define __savefpr3(Gprs)                     \
  406.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  407.     stfd    f31,  -8(r12)                    ;\
  408.     stfd    f30, -16(r12)                    ;\
  409.     stfd    f29, -24(r12)
  410.  
  411. #define __savefpr4(Gprs)                     \
  412.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  413.     bl      __savefpr_28
  414.  
  415. #define __savefpr5(Gprs)                     \
  416.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  417.     bl      __savefpr_27
  418.  
  419. #define __savefpr6(Gprs)                     \
  420.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  421.     bl      __savefpr_26
  422.  
  423. #define __savefpr7(Gprs)                     \
  424.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  425.     bl      __savefpr_25
  426.  
  427. #define __savefpr8(Gprs)                     \
  428.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  429.     bl      __savefpr_24
  430.  
  431. #define __savefpr9(Gprs)                     \
  432.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  433.     bl      __savefpr_23
  434.  
  435. #define __savefpr10(Gprs)                    \
  436.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  437.     bl      __savefpr_22
  438.  
  439. #define __savefpr11(Gprs)                    \
  440.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  441.     bl      __savefpr_21
  442.  
  443. #define __savefpr12(Gprs)                    \
  444.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  445.     bl      __savefpr_20
  446.  
  447. #define __savefpr13(Gprs)                    \
  448.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  449.     bl      __savefpr_19
  450.  
  451. #define __savefpr14(Gprs)                    \
  452.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  453.     bl      __savefpr_18
  454.  
  455. #define __savefpr15(Gprs)                    \
  456.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  457.     bl      __savefpr_17
  458.  
  459. #define __savefpr16(Gprs)                    \
  460.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  461.     bl      __savefpr_16
  462.  
  463. #define __savefpr17(Gprs)                    \
  464.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  465.     bl      __savefpr_15
  466.  
  467. #define __savefpr18(Gprs)                    \
  468.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  469.     bl      __savefpr_14
  470.  
  471. #define __savefpr19(Gprs)                    \
  472.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  473.     bl      __savefpr_13
  474.  
  475.  
  476.  
  477. //
  478. // __restgpr0  Used to restore only the GPR storing the link register.
  479. //  ...
  480. // __restgpr17 Used to restore 17 GPRs and the one storing the link register.
  481. //
  482. //
  483. // These macros generate the end of a function's epilogue.  The link register
  484. // is restored from the one reserved non-volatile.  Next, each of the saved off
  485. // non-volatile GPRs, including the one in which the return address was stored
  486. // is restored.  This restoration is done relative to r1 which was already set
  487. // to the caller's value and is done inline or through use of the millicode
  488. // routines.  In either case, a blr is done to return to the caller.  Note that
  489. // the millicode routines are branched to so that the blr there will return
  490. // program flow to the caller.
  491. //
  492.  
  493. #define __restgpr0        \
  494.     mtlr    r31           ;\
  495.     lwz     r31, -4(r1)   ;\
  496.     blr
  497.  
  498. #define __restgpr1        \
  499.     mtlr    r30           ;\
  500.     lwz     r30, -8(r1)   ;\
  501.     lwz     r31, -4(r1)   ;\
  502.     blr
  503.  
  504. #define __restgpr2        \
  505.     mtlr    r29           ;\
  506.     lwz     r29, -12(r1)  ;\
  507.     lwz     r30,  -8(r1)  ;\
  508.     lwz     r31,  -4(r1)  ;\
  509.     blr
  510.  
  511. #define __restgpr3        \
  512.     mtlr    r28           ;\
  513.     lwz     r28, -16(r1)  ;\
  514.     lwz     r29, -12(r1)  ;\
  515.     lwz     r30,  -8(r1)  ;\
  516.     lwz     r31,  -4(r1)  ;\
  517.     blr
  518.  
  519. #define __restgpr4        \
  520.     mtlr    r27           ;\
  521.     b       __restgpr_27
  522.  
  523. #define __restgpr5        \
  524.     mtlr    r26           ;\
  525.     b       __restgpr_26
  526.  
  527. #define __restgpr6        \
  528.     mtlr    r25           ;\
  529.     b       __restgpr_25
  530.  
  531. #define __restgpr7        \
  532.     mtlr    r24           ;\
  533.     b       __restgpr_24
  534.  
  535. #define __restgpr8        \
  536.     mtlr    r23           ;\
  537.     b       __restgpr_23
  538.  
  539. #define __restgpr9        \
  540.     mtlr    r22           ;\
  541.     b       __restgpr_22
  542.  
  543. #define __restgpr10       \
  544.     mtlr    r21           ;\
  545.     b       __restgpr_21
  546.  
  547. #define __restgpr11       \
  548.     mtlr    r20           ;\
  549.     b       __restgpr_20
  550.  
  551. #define __restgpr12       \
  552.     mtlr    r19           ;\
  553.     b       __restgpr_19
  554.  
  555. #define __restgpr13       \
  556.     mtlr    r18           ;\
  557.     b       __restgpr_18
  558.  
  559. #define __restgpr14       \
  560.     mtlr    r17           ;\
  561.     b       __restgpr_17
  562.  
  563. #define __restgpr15       \
  564.     mtlr    r16           ;\
  565.     b       __restgpr_16
  566.  
  567. #define __restgpr16       \
  568.     mtlr    r15           ;\
  569.     b       __restgpr_15
  570.  
  571. #define __restgpr17       \
  572.     mtlr    r14           ;\
  573.     b       __restgpr_14
  574.  
  575.  
  576. //
  577. // __restfpr0  Restores no FPRs.
  578. //  ...
  579. // __restfpr19 Restores 19 FPRs.
  580. //
  581. //  Gprs - Number of GPRs saved (not including the link register).
  582. // 
  583. // Restore the number of FPRs specified inline or by branching to the
  584. // appropriate millicode procedure.  Note that r1 is aligned on an 8 byte
  585. // boundary.
  586. //
  587. #define __restfpr0(Gprs)
  588.  
  589. #define __restfpr1(Gprs)                     \
  590.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  591.     lfd     f31,  -8(r12)
  592.  
  593. #define __restfpr2(Gprs)                     \
  594.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  595.     lfd     f31,  -8(r12)                    ;\
  596.     lfd     f30, -16(r12)
  597.  
  598. #define __restfpr3(Gprs)                     \
  599.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  600.     lfd     f31,  -8(r12)                    ;\
  601.     lfd     f30, -16(r12)                    ;\
  602.     lfd     f29, -24(r12)
  603.  
  604. #define __restfpr4(Gprs)                     \
  605.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  606.     bl      __restfpr_28
  607.  
  608. #define __restfpr5(Gprs)                     \
  609.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  610.     bl      __restfpr_27
  611.  
  612. #define __restfpr6(Gprs)                     \
  613.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  614.     bl      __restfpr_26
  615.  
  616. #define __restfpr7(Gprs)                     \
  617.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  618.     bl      __restfpr_25
  619.  
  620. #define __restfpr8(Gprs)                     \
  621.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  622.     bl      __restfpr_24
  623.  
  624. #define __restfpr9(Gprs)                     \
  625.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  626.     bl      __restfpr_23
  627.  
  628. #define __restfpr10(Gprs)                    \
  629.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  630.     bl      __restfpr_22
  631.  
  632. #define __restfpr11(Gprs)                    \
  633.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  634.     bl      __restfpr_21
  635.  
  636. #define __restfpr12(Gprs)                    \
  637.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  638.     bl      __restfpr_20
  639.  
  640. #define __restfpr13(Gprs)                    \
  641.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  642.     bl      __restfpr_19
  643.  
  644. #define __restfpr14(Gprs)                    \
  645.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  646.     bl      __restfpr_18
  647.  
  648. #define __restfpr15(Gprs)                    \
  649.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  650.     bl      __restfpr_17
  651.  
  652. #define __restfpr16(Gprs)                    \
  653.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  654.     bl      __restfpr_16
  655.  
  656. #define __restfpr17(Gprs)                    \
  657.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  658.     bl      __restfpr_15
  659.  
  660. #define __restfpr18(Gprs)                    \
  661.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  662.     bl      __restfpr_14
  663.  
  664. #define __restfpr19(Gprs)                    \
  665.     addi    r12, r1, -(ALIGN8((Gprs+1)*4))   ;\
  666.     bl      __restfpr_13
  667.  
  668.  
  669. #endif // _KXPPC_C_HEADER_
  670.  
  671.  
  672. //**************************************************************************/
  673. //
  674. //      PPC Linkage support macros
  675. //
  676. //
  677. //**************************************************************************/
  678.  
  679. //
  680. // Offset to backchain
  681. //
  682. #define STK_RSP         0
  683.  
  684. //
  685. // Size of stack header (backchain + reserved)
  686. //
  687. #define STK_HDR_SZ      8
  688.  
  689. //
  690. // Offsets to function arguments pushed onto stack
  691. //
  692. #define STK_P0          STK_HDR_SZ
  693. #define STK_P1          (STK_P0+4)
  694. #define STK_P2          (STK_P0+8)
  695. #define STK_P3          (STK_P0+12)
  696. #define STK_P4          (STK_P0+16)
  697. #define STK_P5          (STK_P0+20)
  698. #define STK_P6          (STK_P0+24)
  699. #define STK_P7          (STK_P0+28)
  700.  
  701. //
  702. // Minimum stack frame size (function arguments, backchain, and reserved)
  703. //
  704. #define STK_MIN_FRAME   40
  705.  
  706.  
  707. #ifndef _KXPPC_C_HEADER_
  708.  
  709. //
  710. // The following macros are provided for assembly language programmers.
  711. //
  712. //
  713. // Define procedure entry/exit macros
  714. //
  715. // Name  - Name of the nested procedure entry
  716. // Fsize - Amount of local storage and additional argument passing space
  717. //           Use 0 if no local storage or additional argument passing
  718. //           space is needed.
  719. // Gprs  - Number of general purpose registers to save  (max 17)
  720. // Fprs  - Number of floating point registers to save  (max 19)
  721. //
  722. //
  723. // For primary entry points (NESTED_ENTRY, LEAF_ENTRY), a function table
  724. // entry (for debugging, exception handling) is built.
  725. //
  726. // For all entry points, a function descriptor is built.
  727. //
  728. //
  729. // NESTED_ENTRY is used for routines that call other routines; a stack
  730. // frame is acquired and registers are saved.
  731. //
  732. // LEAF_ENTRY is used for routines that do not call other routines; no stack
  733. // frame is acquired and no registers are saved.
  734. //
  735. //
  736. // NESTED_ENTRY_EX and LEAF_ENTRY_EX are used when an exception or termination
  737. // handler is provided.
  738. //
  739. //
  740. // The PROLOGUE_END macro must be coded in all routines that used NESTED_ENTRY
  741. // or NESTED_ENTRY_EX, because the function table entry refers to the label
  742. // that it generates.
  743. //
  744. // SPECIAL_ENTRY is a used for routines that function like a LEAF_ENTRY
  745. // but require some prologue for exception handling. An example of this
  746. // is a stack checking routine which must make a system call to get
  747. // the TEB pointer. The efficiency of a LEAF_ENTRY is needed, but also
  748. // parts of the NESTED_ENTRY are required for the system call.
  749. //
  750. // Just like the NESTED_ENTRY, SPECIAL_ENTRY requires the PROLOGUE_END
  751. // macro.
  752. //
  753. // FN_TABLE, DUMMY_ENTRY, and DUMMY_EXIT are used to construct the "prologues"
  754. // for low-level exception handling code.  These prologues are never executed,
  755. // but are present to allow unwinding through the hand-written, low-level
  756. // assembly code.
  757.  
  758. //
  759. //  Register Conventions
  760. //  ~~~~~~~~~~~~~~~~~~~~
  761. //  r0          Temporary/scratch
  762. //  r1          Stack Pointer
  763. //  r2          GP (Global Pointer)
  764. //  r3 - r10    Argument Registers
  765. //  r11         Temporary
  766. //  r12         Temporary (also used during prologue/epilogue)
  767. //  r13         Reserved
  768. //  r14 - r31   Non-volatiles
  769. // 
  770. //
  771. // The following is a description of the stack layout for nested calls.  The
  772. // same layout and process is used for all NESTED_ENTRY* macros, below.
  773. //
  774. // The requested number of GPRs (if any) are pushed onto the stack.  The link
  775. // register is saved in this process in a non-volatile register.
  776. //
  777. // Next, the requested number of FPRs are pushed on the stack, below the
  778. // saved GPRs.
  779. //
  780. // Finally, the stack pointer is updated to the new location, and the
  781. // backchain (dynamic link to the previous stack pointer) is written in.
  782. // Note that the stack pointer is always aligned on an 8 byte boundary.
  783. // 
  784. //
  785. //                                               HIGH ADDRESS
  786. //                                              Stack grows down
  787. // Caller's stack pointer
  788. //   R1 ------> | Caller's backchain                   |
  789. //    |         +--------------------------------------+
  790. //    |         | The first GPR is saved at -4 off the |
  791. //    |         | caller's stack pointer.              |
  792. //    |         |                                      |
  793. //    |         |  Saved GPRs (if needed)              |
  794. //    |         |                  +-------------------+
  795. //    |         |                  |  Pad  (if needed) |
  796. //    |         +------------------+-------------------+
  797. //    |    r12->| r12 is used as a base into the FPR   |
  798. //    |         | save area.  It is aligned on an 8    |
  799. //    |         | byte boundary.  Padding (above) is   |
  800. //    |         | inserted if necessary.               |
  801. //    |         |                                      |
  802. //    |         |                                      |
  803. //    |         |  Saved FPRs (if needed)              |
  804. //    |         |                                      |
  805. //    |         +--------------------------------------+ <-------------------
  806. //    |         |                                      |                   ^
  807. //    |         |  Locals (if needed)                  |                   |
  808. //    |         |                                      |                   |
  809. //    |         +--------------------------------------+                 Fsize
  810. //    |         |                                      |                   |
  811. //    |         |  Additional Arguments (if needed)    |                   |
  812. //    |         |                                      |                   v
  813. //    |         +------------------+-------------------+ <-------------------
  814. //    |         |  Parameter Wd 6  |  Parameter Wd 7   |  Argument         ^
  815. //    |         +------------------+-------------------+   Passing Area    |
  816. //    |         |  Parameter Wd 4  |  Parameter Wd 5   |  Wd0 = r3         |
  817. //    |         +------------------+-------------------+   ...             |
  818. //    |         |  Parameter Wd 2  |  Parameter Wd 3   |  Wd7 = r10        |
  819. //    |         +------------------+-------------------+                   |
  820. //    |         |  Parameter Wd 0  |  Parameter Wd 1   |         STK_MIN_FRAME
  821. //    v         +------------------+-------------------+                   |
  822. //   R1'------> |  Back chain (r1) |     Reserved      |                   v
  823. //              +------------------+-------------------+ <-------------------
  824. //              STACK TOP                       Stack grows down
  825. //                                               LOW ADDRESS
  826. //
  827. //  R1 is always aligned on an 8 byte boundary.
  828. //
  829.  
  830. #define NESTED_ENTRY(Name,Fsize,Gprs,Fprs)                              \
  831.     __fntabentry(Name)                                                  ;\
  832.     __begintext(Name)                                                   ;\
  833.     __savegpr##Gprs                                                     ;\
  834.     __savefpr##Fprs(Gprs)                                               ;\
  835.     stwu    r1, -ALIGN8(STK_MIN_FRAME+((Gprs)+1)*4+(Fprs)*8+(Fsize))(r1)
  836.  
  837. #define NESTED_ENTRY_EX(Name,Fsize,Gprs,Fprs,LangHandler,Scope)         \
  838.     __fntabentryEx(Name,LangHandler,Scope)                              ;\
  839.     __begintext(Name)                                                   ;\
  840.     __savegpr##Gprs                                                     ;\
  841.     __savefpr##Fprs(Gprs)                                               ;\
  842.     stwu    r1, -ALIGN8(STK_MIN_FRAME+((Gprs)+1)*4+(Fprs)*8+(Fsize))(r1)
  843.  
  844. #define NESTED_EXIT(Name,Fsize,Gprs,Fprs)                               \
  845. Name##.epi:                                                              \
  846.     addi    r1, r1, ALIGN8(STK_MIN_FRAME+((Gprs)+1)*4+(Fprs)*8+(Fsize)) ;\
  847.     __restfpr##Fprs(Gprs)                                               ;\
  848.     __restgpr##Gprs                                                     ;\
  849. Name##.end:
  850.  
  851. #define PROLOGUE_END(Name)  \
  852. Name##.body:
  853.  
  854. #define ALTERNATE_ENTRY(Name)  \
  855.     __begintext(Name)
  856.  
  857. #define LEAF_ENTRY(Name)  \
  858.     __begintext(Name)     ;\
  859. Name##.body:
  860.  
  861. #define LEAF_ENTRY_EX(Name,LangHandler,Scope)   \
  862.     __fntabentryEx(Name,LangHandler,Scope)      ;\
  863.     __begintext(Name)                           ;\
  864. Name##.body:
  865.  
  866. #define SPECIAL_ENTRY(Name) \
  867.     __fntabentry(Name)      ;\
  868.     __begintext(Name)
  869.  
  870. #define DUMMY_ENTRY(Name)  \
  871.     __begintext(Name)
  872.  
  873. #define LEAF_EXIT(Name) \
  874.     blr                 ;\
  875. Name##.end:
  876.  
  877. #define ALTERNATE_EXIT(Name)  \
  878.     blr
  879.  
  880. #define SPECIAL_EXIT(Name) \
  881.     blr                    ;\
  882. Name##.end:
  883.  
  884. #define DUMMY_EXIT(Name)  \
  885. Name##.end:
  886.  
  887. #define FN_TABLE(Name)     \
  888.     __fntabentry(Name)
  889.  
  890. #define FN_TABLE_EX(Name,ExHandler,Data)  \
  891.     __fntabentryEx(Name,ExHandler,Data)
  892.  
  893.  
  894. //
  895. // Internal macros, used by the above (not for programmer use)
  896. //
  897.  
  898. #define __fntabentry(Name)                        \
  899.     .pdata                                        ;\
  900.     .align  2                                     ;\
  901.     .long   Name                                  ;\
  902.     .long   ( ( ((Name##.body-Name) >> 2) |        \
  903.              (((Name##.end-Name) >> 2) << 8) ) |   \
  904.               (1 << 30))
  905.  
  906. #define __fntabentryEx(Name,ExHandler,Data)       \
  907.     .pdata                                        ;\
  908.     .align  2                                     ;\
  909.     .long   Name                                  ;\
  910.     .long   ( ((Name##.body-Name) >> 2) |          \
  911.               (((Name##.end-Name) >> 2) << 8) |    \
  912.               (1 << 31 ) | (1 << 30))             ;\
  913.     .text                                         ;\
  914.     .align  3                                     ;\
  915.     .long   ExHandler                             ;\
  916.     .long   Data
  917.  
  918. #define __begintext(Name)   \
  919.     .text                   ;\
  920.     .align  2               ;\
  921.     .globl  Name            ;\
  922. Name:
  923.  
  924. #endif // _KXPPC_C_HEADER_
  925.  
  926. #endif // _KXPPC_
  927.